package com.tyx.chargingpile.util;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;

public final class Util {

	private Util() {
	}

	/**
	 * 测试使用的主函数
	 * 
	 *            命令行参数
	 */
	// public static void main(String[] args) {
	// int ntest = 200;
	// byte val;
	// byte[] res = IntToHexStr(ntest);
	// val = res[0];
	// //
	// byte[] val2 = new byte[] { 0x11, (byte) 0xaa, (byte) 0xbb };
	// byte[] res2 = new byte[6];
	// HexToAscii(val2, res2, 3);
	//
	// byte[] val3 = new byte[] { '1', 'a', '2', 'b' };
	// int res3 = HexStrToInt(val3, 4);
	// }


	//////////////////////////////////////////////////////////
	/*
	 * 将16进制的字节值转换为ASCII表示，如：\x1转换为：“1”，\xF转换为："F"
	 * 
	 * */
	public static byte hexByteToAscii(byte curChar) {
		if (curChar >= 0x00 && curChar <= 0x09) {
			// 0-9
			return (byte) (curChar + 0x30);
		}
		else if (curChar >= 0x0A) {
			// A-F
			return (byte) (curChar + 0x37);
		}
		else {
			return 0x30;
		}
	}

	// ///////////////////////////////////////////////////////
	// ************************************
	// 功 能: 将一个十六进制字节串转换成 ASCII 码表示的字符串
	// 函 数 名: HexToAscii
	// 返 回 值: void
	// 作 者： 陶志高
	// 参 数: unsigned char * pHex 要转换的十六进制数字节串首地址
	// 参 数: unsigned char * pAscii 转换后的 ASCII 码表示的字符串的首地址
	// 参 数: int nHexLen 要转换的十六进制数的长度（字节数）
	// 说明 不对数组越界进行检查 例: "\x12\x34\x56\x78"->"12345678" nHexLen=4 转换后8字节
	// ************************************
	public static String HexToAscii(byte[] pHex, int nHexLen) {
		byte curChar;
		byte[] pAscii = new byte[nHexLen*2];
		for (int nChar = 0; nChar < nHexLen; ++nChar) {
			// 高四字节
			curChar = (byte) ((pHex[nChar] & 0xF0) >> 4);
			pAscii[nChar * 2] = hexByteToAscii( curChar );
			// 低四字节
			curChar = (byte) (pHex[nChar] & 0x0F);
			pAscii[nChar * 2 + 1] = hexByteToAscii( curChar );
		}
		return new String(pAscii);
	}

	// ************************************
	// 功 能: 将一个 ASCII 码表示的十六进制字符串转换成十六进制的字节串(值)
	// 函 数 名: AsciiToHex
	// 返 回 值: BOOL 不是0-9 A-F a-f返回FALSE
	// 作 者： 陶志高
	// 参 数: unsigned char * pAscii 要转换的 ASCII 码表示的十六进制字符串的首地址
	// 参 数: unsigned char * pHex 转换后的十六进制数字节串首地址
	// 参 数: int nASCLen 要转换的 ASCII 码表示的十六进制字符串的长度（字节数）
	// 说明：自动去掉空格，不对数组越界进行检查, 例 "12 34 5678"->"\x12\x34\x56\x78" nlen=8 转换后4字节
	// ************************************
	public static byte[] AsciiToHex(byte[] pAscii, int nASCLen) {
		byte curChar,curHex = 0;
		byte[] pHex = new byte[nASCLen/2];
		int nHex = 0, nSpace = 0;
		boolean bHight = false;
		for (int nChar = 0; nChar < nASCLen; ++nChar) {
			// 第N个字符
			curChar = pAscii[nChar];
			if (curChar == ' ') {
				// 去掉空格
				++nSpace;
				continue;
			}
			// 对应的16进制数
			nHex = (nChar - nSpace) / 2;
			bHight = (((nChar - nSpace) % 2) == 1) ? false : true;			
			if (curChar >= '0' && curChar <= '9') {
				// 0-9
				curHex = (byte) (curChar - 0x30);
			}else if (curChar >= 'a' && curChar <= 'f') {
				// a-f
				curHex = (byte) (curChar - 0x57);
			}else if (curChar >= 'A' && curChar <= 'F') {
				// A-F
				curHex = (byte) (curChar - 0x37);
			}
			if (bHight) {
				pHex[nHex] = (byte) (curHex << 4);
			} else {
				pHex[nHex] = (byte) (pHex[nHex] + curHex);
			}
		}
		return pHex;
	}

	// ************************************
	// 函数功能: 16进制字符串转为整型
	// 函数全名: HexStrToInt
	// 作 者: 陶志高
	// 访问权限: public
	// 返回类型: TXTCONVERSIONE_API BOOL WINAPI
	// 参数说明: char * pHexStr 如：“1A2B”最多8个字符，4字节
	// 参数说明: int * intVal 转换后的int值6699
	// 参数说明: int hexlen 字符串长度
	// ************************************
	public static int HexStrToInt(byte[] pHexStr, int hexlen) {
		int intVal = 0;
		byte[] pHex = new byte[4];
		pHex = AsciiToHex(pHexStr,hexlen);
		intVal = HexToInt(pHex, 0, hexlen / 2);
		return intVal;
	}
	
	// ************************************
	// 函数功能: 16进制数组值转为整型
	// 函数全名: HexToInt
	// 作 者: 陶志高
	// 访问权限: public
	// 返回类型: TXTCONVERSIONE_API BOOL WINAPI
	// 参数说明: char * pHex 如：0x1A2B,最多4字节
	// 参数说明: int * intVal 转换后的int值6699
	// 参数说明: int hexlen
	/*
	 * 将hex的startpos开始的连续nbytes字节转换为INT数据 如：0x000000C8转换为200
	 */
	// ************************************
	public static int HexToInt(byte[] hex, int startpos, int nbytes) {
		int ret = 0;
		final int endpos = startpos + nbytes;
		for (int i = startpos; i < endpos; ++i) {
			ret <<= 8;
			ret |= hex[i] & 0xFF;
		}
		return ret;
	}

	// 0x1A 0x1B 装换为6699 nlength=4 最长只能处理4个字节
	public static int HexToint(byte[] data, int nbytes) {
		return HexToInt(data,0,nbytes);
	}
	// ************************************
	// 函数功能: 整型转为16进制数组
	// 函数全名: IntToHex
	// 作 者: 陶志高
	// 访问权限: public
	// 返回类型: TXTCONVERSIONE_API BOOL WINAPI
	// 参数说明: char * pHexSource 最多4字节,如：36转换后为0x00000024
	// 参数说明: int intVal 要转换的整数
	// 参数说明: int* hexlen
	// 转换后的HEX长度,总长度为4字节，hexlen为实际数据字节长度，如36转换后为0x00000024，hexlen＝1
	// ************************************
	public static byte[] IntToHex(int intVal) {
		return new byte[] { (byte) (0x000000ff & (intVal >>> 24)),
				(byte) (0x000000ff & (intVal >>> 16)), 
				(byte) (0x000000ff & (intVal >>> 8)), 
				(byte) (0x000000ff & (intVal)) };
	}

	// ************************************
	// 函数功能: 整型转为16进制字符串
	// 函数全名: IntToHexStr
	// 作 者: 陶志高
	// 访问权限: public
	// 返回类型: TXTCONVERSIONE_API BOOL WINAPI
	// 参数说明: char * pHexStr 最多8字节,如：36转换后为0x00000024
	// 参数说明: int intVal 要转换的整数
	// 参数说明: int * hexlen 转换后的HEX长度
	// ************************************
	public static byte[] IntToHexStr(int intVal) {
		byte[] pHex = IntToHex(intVal);
		return HexToAscii(pHex, 4).getBytes();
	}

	// 把string以byte显示 123456 \x31\x32\x33\x34\x35\x36
	public static byte[] String2Byte(String data) {
		byte[] sendBytes = null;
		try {
			sendBytes = data.getBytes("UTF8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sendBytes;
	}

	// 把byte以string显示 \x31\x32\x33\x34\x35\x36 123456
	public static String Byte2String(byte[] data) {
		String sendString = null;
		try {
			sendString = new String(data, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sendString;
	}

	public static byte[] Str2MCMDate(String mcmDate) {
		byte[] bytes = new byte[4];
		int intYear = Integer.parseInt(mcmDate.substring(2, 4));
		int intMonth = Integer.parseInt(mcmDate.substring(4, 6));
		int intDay = Integer.parseInt(mcmDate.substring(6, 8));
		int intHour = Integer.parseInt(mcmDate.substring(8, 10));
		int intMinute = Integer.parseInt(mcmDate.substring(10, 12));
		int intSec = Integer.parseInt(mcmDate.substring(12));
		int intValue = (intYear & 0x3F) << 26;
		intValue += (intMonth & 0x0F) << 22;
		intValue += (intDay & 0x1F) << 17;
		intValue += (intHour & 0x1F) << 12;
		intValue += (intMinute & 0x3F) << 6;
		intValue += (intSec & 0x3F);
		bytes = IntToHex(intValue);
		return bytes;
	}

	/**
	 * c
	 * @param strData 如果传入字符为空，默认为00
	 * @return
	 */
	public static byte[] String2BCD(String strData) {
		// 如果传入的字符为空，默认00
		if (strData == null || strData.equals("")){
			strData = "00";
		}
		// 如果该数据的长度是奇数，则前补0
		if (strData.length() % 2 !=0){
			strData = "0" +strData;
		}
		byte[] inData = String2Byte(strData);
		byte[] retData = AsciiToHex(inData, strData.length());
		return retData;
	}

	// 0x12 0x34 0x56 -->123456 nHexLen=3 转换后6字节
	public static String BCD2String(byte[] bData) {
		String retData = HexToAscii(bData, bData.length);
		return retData;
	}

	/**
	 * 根据长度前补零
	 * @param data
	 * @param length
	 * @return
	 */
	public static String FronFillZero(String data, int length){
		int len = data.length();
		int fillLen = length - len;
		StringBuffer stringBuffer = new StringBuffer();
		if (fillLen >=0 ){
			for (int i = 0; i < fillLen; i++){
				stringBuffer.append("0");
			}
			stringBuffer.append(data);
			return stringBuffer.toString();
		}else {
			return data;
		}
	}

	/**
	 * Double强转int类型，防止精度丢失
	 * 例如2.03要转到203，防止丢失精度变为202
	 * @param dou1
	 * @param dou2
	 * @return
	 */
	public static int formatDoubleTOInt(double dou1,double dou2){
		BigDecimal big1 = new BigDecimal(Double.valueOf(dou1)).setScale(2, BigDecimal.ROUND_HALF_UP);
		BigDecimal big2 = new BigDecimal(Double.valueOf(dou2));
		return big1.multiply(big2).intValue();
	}
}
